package com.stoa.floatlib.core

import android.app.Activity
import android.content.Context
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import android.widget.FrameLayout
import com.stoa.floatlib.MainIconStoaView
import com.stoa.floatlib.R
import com.stoa.floatlib.core.StoaIntent.Companion.MODE_SINGLE_INSTANCE
import com.stoa.floatlib.widget.StoaFloatFrameLayout

internal class NormalStoaFloatViewManager : StoaFloatManagerInterface {
    private var mActivityStoaViews: MutableMap<Activity, MutableMap<String, AbsStoaFloatView>>
    private var mGlobalSingleStoaViews: MutableMap<String, GlobalSingleStoaViewInfo>
    private var mContext: Context
    private val viewTag: String?

    constructor(mContext: Context, viewTag: String?) {
        this.viewTag = viewTag
        this.mContext = mContext
        mActivityStoaViews = mutableMapOf()
        mGlobalSingleStoaViews = mutableMapOf()
    }

    override fun attach(stoaIntent: StoaIntent) {
        val stoaFloatView = stoaIntent.target
        val stoaFloatViews: MutableMap<String, AbsStoaFloatView>?
        if (mActivityStoaViews[stoaIntent.activity] == null) {
            stoaFloatViews = mutableMapOf()
            mActivityStoaViews[stoaIntent.activity] = stoaFloatViews
        } else {
            stoaFloatViews = mActivityStoaViews[stoaIntent.activity]
        }

        if (stoaIntent.mode == MODE_SINGLE_INSTANCE) {
            stoaFloatViews?.get(stoaIntent.tag)?.let {
                it.updateViewLayout(stoaIntent.tag, true)
                return
            }
        }

        stoaFloatViews?.put(stoaIntent.tag, stoaFloatView)
        stoaFloatView.setMode(stoaIntent.mode)
        stoaFloatView.setBundle(stoaIntent.bundle)
        stoaFloatView.setTag(stoaIntent.tag)
        stoaFloatView.setActivity(stoaIntent.activity)
        stoaFloatView.performCreate(mContext)

        //在全局dokitviews中保存该类型的
        if (stoaIntent.mode == MODE_SINGLE_INSTANCE && !mGlobalSingleStoaViews.containsKey(
                stoaFloatView.getTag()
            )
        ) {
            mGlobalSingleStoaViews[stoaFloatView.getTag()] =
                createGlobalSingleInfo(stoaFloatView)
        }

        //得到activity window中的根布局
        val mDecorView = stoaIntent.activity.window.decorView as FrameLayout

        //往DecorView的子RootView中添加dokitView
        if (stoaFloatView.getNormalLayoutParams() != null && stoaFloatView.getRootView() != null) {
            getStoaRootContentView(stoaIntent.activity, mDecorView)
                .addView(
                    stoaFloatView.getRootView(),
                    stoaFloatView.getNormalLayoutParams()
                )
            //延迟100毫秒调用
            stoaFloatView.postDelayed(Runnable {
                stoaFloatView.onResume()
            }, 100L)
        }
    }

    private fun getStoaRootContentView(activity: Activity, decorView: FrameLayout): FrameLayout {
        var stoaRootView = decorView.findViewById<FrameLayout>(R.id.stoa_content_view_id)
        if (stoaRootView != null) {
            return stoaRootView
        }

        stoaRootView = StoaFloatFrameLayout(activity)
        stoaRootView.clipChildren = true
        stoaRootView.requestFocus()
        stoaRootView.id = R.id.stoa_content_view_id
        stoaRootView.isFocusable = true
        stoaRootView.isFocusableInTouchMode = true

        val layoutParam = FrameLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT
        )
        stoaRootView.layoutParams = layoutParam
        decorView.addView(stoaRootView)
        return stoaRootView
    }

    private fun createGlobalSingleInfo(stoaFloatView: AbsStoaFloatView): GlobalSingleStoaViewInfo {
        return GlobalSingleStoaViewInfo(
            stoaFloatView,
            stoaFloatView.getMode()!!,
            stoaFloatView.getBundle()!!,
            stoaFloatView.getTag()
        )
    }

    override fun detach() {
        detach(MainIconStoaView::class.java.simpleName)
    }

    override fun detach(tag: String) {
        for (activity in mActivityStoaViews.keys) {
            val mutableMap = mActivityStoaViews[activity]
            val stoaFloatView = mutableMap?.get(tag) ?: continue
            stoaFloatView.getRootView()?.run {
                visibility = GONE
                getStoaRootContentView(
                    activity,
                    activity.window.decorView as FrameLayout
                ).removeView(this)
            }

            activity.window.decorView.requestLayout()
            stoaFloatView.performDestroy()
            mutableMap.remove(tag)
        }
    }

    override fun detach(stoaFloatView: AbsStoaFloatView) {
        detach(stoaFloatView.getTag())
    }

    override fun detachAll() {

    }

    override fun getStoaFloatView(activity: Activity, tag: String): IStoaFloatView {
        return mActivityStoaViews[activity]!![tag]!!
    }

    override fun getStoaFloatViews(activity: Activity, tag: String): Map<String, IStoaFloatView> {
        return mapOf()
    }

    override fun onActivityCreate(activity: Activity) {
        for (value in mGlobalSingleStoaViews.values) {
            value.run {
                val stoaIntent = StoaIntent(mAbsStoaViewClass)
                stoaIntent.mode = value.mMode
                stoaIntent.bundle = value.mBundle
                attach(stoaIntent)
            }
        }
    }

    override fun onActivityResume(activity: Activity) {
        if (mActivityStoaViews.isEmpty()) {
            return
        }
        val stoaViewMap = mActivityStoaViews[activity]
        mGlobalSingleStoaViews.values.forEach {
            stoaViewMap?.let { map ->
                val exitFloatView: AbsStoaFloatView? = map[it.mTag]
                if (exitFloatView?.getRootView() != null) {
                    exitFloatView.getRootView()?.visibility = GONE
                    exitFloatView.updateViewLayout(exitFloatView.viewTag, true)
                    exitFloatView.onResume()
                } else {
                    val stoaIntent = StoaIntent(it.mAbsStoaViewClass)
                    stoaIntent.mode = it.mMode
                    stoaIntent.bundle = it.mBundle
                    attach(stoaIntent)
                }
            }
        }
    }

    override fun onActivityPause(activity: Activity) {

    }

    override fun notifyForeground(activity: Activity) {
        for (map in mActivityStoaViews.values) {
            for (absStoaFloatView in map.values) {
                absStoaFloatView.onEnterForeground()
            }
        }
    }

    override fun notifyBackground(activity: Activity) {
        for (map in mActivityStoaViews.values) {
            for (absStoaFloatView in map.values) {
                absStoaFloatView.onEnterBackground()
            }
        }
    }

    override fun resumeAndAttachStoaViews(activity: Activity) {
        onActivityCreate(activity)
//        onActivityResume(activity)
    }
}